# -*- coding: utf-8 -*-
# $Id: batch.py 28 2010-01-13 17:46:22Z gkuznets $

# mpcheckup
# Copyright 2008, 2009 Grigoriy Kuznetsov (gkuznets@yandex.ru)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from datetime import *
import logging
from PyQt4 import QtCore
from PyQt4.QtCore import QTime

from checkup import Checkup
checkup = Checkup.instance()

class Batch(object):
    """Пачка работ"""
    
    # Хранилище всех пачек
    __bdict = {}
    # Текущая выделенная пачка
    selected_batch = None
    # Суммарное число работ во всех пачкам
    total_papers = 0
    
    @staticmethod
    def __addBatch(batch):
        Batch.__bdict[batch.no] = batch
    
    @staticmethod
    def all():
        return Batch.__bdict.values()
    
    @staticmethod
    def find(bno):
        return Batch.__bdict.get(bno, None)
    
    def __init__(self, no, pcount):
        """Конструктор"""
        # Число работ в пачке
        self.papers_count = pcount
        # Увеличиваем суммарное число работ
        Batch.total_papers += pcount
        # Номер пачки
        self.no = no
        
        # Выполненность проверок
        self.__progress = [{}, {}] # Пустые множества проверенных задач по первой и второй проверке
        #self.jobs = {}
        #for p in xrange(globals.problems_count):
        #  for c in xrange(globals.checkups_count):
        #    self.jobs[(p, c)] = {'done':False}
        # Число проверенных задач
        #self.jobs_complete = 0
        
        # Временные атрибуты
        self.total_time = QTime(0, 0, 0)
        self.current_time = QTime(0, 0, 0)
        
        # текущая проверяющая группа
        self.group = None
        
        # Номер текущей проверки
        #self.checkup = 0
        
        # Признак проблемной пачки
        self.marked = False
        # Признак пачки, засидевшейся на проверке
        self.lazy = False
        # Признак того, что осталась ровно одна непроверенная задача
        self.one_problem_left = False
        
        # Добавляем себя в глобальное хранилище пачек
        Batch.__addBatch(self)
        
        # Сообщение в лог
        logging.info("Добавлена пачка %s." % str(self.name()))
        
    def checkedProblems(self, cnum):
        """Список проверенных задач по проверке cnum"""
        return self.__progress[cnum].keys()
    
    def completeProblems(self, cnum=None):
        """Количество проверенных задач"""
        if cnum is not None:
            return len(self.checkedProblems(cnum))
        else:
            return len(self.checkedProblems(0)) + len(self.checkedProblems(1))
    
    @staticmethod
    def totalCompleteProblems(cnum=None):
        result = 0
        for b in Batch.all():
            result += b.completeProblems(cnum)
        return result
    
    # pnum - problem_no
    # cnum - checkup_no
    def completeProblem(self, pnum, cnum=None):
        from group import Group
        # Если номер проверки cnum явно не указан, то угадываем его
        if cnum is None:
            if self.__progress[0].get(pnum, None) is None:
                cnum = 0
            else:
                cnum = 1
        # Разбираемся со временем проверки
        elapsed_secs = self.current_time.secsTo(QTime.currentTime())
        self.__progress[cnum][pnum] = (self.current_time, self.current_time.addSecs(elapsed_secs))
        self.total_time = self.total_time.addSecs(elapsed_secs)
        # Увеличиваем счетчик проверенных работ в группе проверки
        group = Group.find(pnum)
        group.papers_complete[cnum] += self.papers_count
        # Сообщение в лог
        logging.info("Пачка %s пришла с проверки задачи %d. Проверена за %0.1f минут" % (str(self.name()), pnum+1, elapsed_secs/60.0))
    
    def sendToProblem(self, pno):
        """Послать пачку на проверку задачи pno"""
        from group import Group
        assert(self.group is None)
        # Если задача не проверена по первому разу или не проверена по второму разу и
        # открыта вторая проверка, то посылаем на проверку
        if pno not in self.__progress[0].keys() or \
           (pno not in self.__progress[1].keys()):
            self.group = Group.find(pno)
            self.group.addBatch(self)
            self.current_time = QTime.currentTime()
            # Сообщение в лог
            logging.info("Пачка %s ушла на проверку задачи %d" % (str(self.name()), pno + 1))
    
    def takeBack(self, complete=True):
        if self.group != None:
            self.group.takeBatch(self)
            if complete:
                self.completeProblem(pnum=self.group.index)
                self.update_checkup()
            self.group = None
    
    def name(self):
        if self.no > 9:
            return str(self.no)
        else:
            return "0" + str(self.no)
    
    def select(self):
        """makes batch selected"""
        Batch.selected_batch = self
    
    def update_checkup(self):
        """Увеличивает, если нужно номер текущей проверки для пачки"""
        if self.completeProblems(0) == 6:
            self.checkup = 1
    
    def selected(self):
        return (Batch.selected_batch == self)
